namespace Microsoft.Robotics.Tracing
{
    using System;

    /* Tracing facade class
     * We use static interface to streamline usage of this class.
     * 
     * Sample usage of MSRobotics trace facade
     * 
        private static void TestSomeTracing()
        {   
            // Example of a simple one-liner Info trace example
                TraceOut.Info(TraceContexts.Nav, "Testing trace {0}", 100);
            
                result in debugger output window/log file/DebugView.exe
                2013-10-14 16:25:25.665        Nav        Testing trace 100
      
            // Example of a simple one-liner Error and warning traces
                TraceOut.Error(TraceContexts.NAV, "Testing trace {0}", 100);
                TraceOut.Warning(TraceContexts.Test, "Testing trace {0}", 100);
      
                result in debugger output window/log file/DebugView.exe
                2013-10-14 16:25:25.665        ERR!  Navigation  Testing trace 100
                2013-10-14 16:25:25.665        WRN!  Test        Testing trace 100

            // Example of a one-liner Error with custom context (aka category)
                TraceOut.Error(TraceContexts.FromString("CustomCategory" TraceContexts.Nav), "Testing trace {0}", 100);
      
                result in debugger output window/log file/DebugView.exe
                2013-10-14 16:25:25.665        ERR!  Nav.CustomCategory        Testing trace 100

            // Example of an Error with custom context (aka category) that has been pre-created. Equivalent of previous example
                TraceContext ctxt =  TraceContexts.FromString("CustomCategory" TraceContexts.Nav);                 
                TraceOut.Error(ctxt, "Testing trace {0}", 100);
      
                result in debugger output window/log file/DebugView.exe
                2013-10-14 16:25:25.665        ERR!  Nav.CustomCategory        Testing trace 100
      
            // Example of an Error with custom context (aka category) that has been pre-created. Equivalent of previous example,
            // only the context object has been pre-created (i.e. at class contruction time)
                TraceContext ctxt =  TraceContexts.FromString("CustomCategory" TraceContexts.Nav);                 
                TraceOut.Error(ctxt, "Testing trace {0}", 100);
      
                result in debugger output window/log file/DebugView.exe
                2013-10-14 16:25:25.665        ERR!  Nav.CustomCategory        Testing trace 100 
     */

    /// <summary>
    /// Tracing facade class
    /// todo: Dynamic enablement of tracing per category (based on context hierarchy) per level
    /// todo: use CorrelationManager.ActivityId to keep track of tracing/error reporting with multiple threads    
    /// </summary>
    public class TraceOut
    {
        /// <summary>
        /// Trace out dispatcher
        /// </summary>
        private static ITraceDispatcher dispatcher = 
            new SimpleTraceDispatcher(new SystemDiagnosticsTraceWriter(new SimpleFormatter()));

        /// <summary>
        /// Canned info level context
        /// </summary>
        private static TraceContext infoLevel = new TraceContext((int)TraceLevelIDs.Information, "INFO", null);

        /// <summary>
        /// Canned warning level context. 
        /// </summary>
        private static TraceContext warningLevel = new TraceContext((int)TraceLevelIDs.Warning, "WRN!", null);

        /// <summary>
        /// Canned error level context
        /// </summary>
        private static TraceContext errorLevel = new TraceContext((int)TraceLevelIDs.Error, "ERR!", null);

        /// <summary>
        /// Canned verbose level context
        /// </summary>
        private static TraceContext verboseLevel = new TraceContext((int)TraceLevelIDs.Verbose, "VERB", null);

        /// <summary>
        /// Gets or sets an instance of trace dispatcher
        /// </summary>
        public static ITraceDispatcher TraceDispatcher 
        { 
            get
            {
                return dispatcher;
            } 

            set
            {
                dispatcher = value;
            } 
        }        

        /// <summary>
        /// Trace verbose level event
        /// </summary>
        /// <param name="context">Tracing context, i.e. category name</param>
        /// <param name="format">Format of the trace</param>
        /// <param name="args">The Arguments</param>
        public static void Verbose(TraceContext context, string format, params object[] args)
        {
            dispatcher.Dispatch(verboseLevel, context, format, args);
        }

        /// <summary>
        /// Trace info level event
        /// </summary>
        /// <param name="context">Tracing context, i.e. category name</param>
        /// <param name="format">Format of the trace</param>
        /// <param name="args">The Arguments</param>
        public static void Info(TraceContext context, string format, params object[] args)
        {
            dispatcher.Dispatch(infoLevel, context, format, args);
        }

        /// <summary>
        /// Trace warning level event
        /// </summary>
        /// <param name="context">Tracing context, i.e. category name</param>
        /// <param name="format">Format of the trace</param>
        /// <param name="args">The Arguments</param>
        public static void Warning(TraceContext context, string format, params object[] args)
        {
            dispatcher.Dispatch(warningLevel, context, format, args);
        }

        /// <summary>
        /// Trace error level event
        /// </summary>
        /// <param name="context">Tracing context, i.e. category name</param>
        /// <param name="format">Format of the trace</param>
        /// <param name="args">The Arguments</param>
        public static void Error(TraceContext context, string format, params object[] args)
        {
            dispatcher.Dispatch(errorLevel, context, format, args);
        }
    }
}
